import { createMemoryHistory, createRouter ,createWebHashHistory, createWebHistory } from "vue-router";
//引入组件
import About from "@/components/1BASE/1base/base1.vue";
import Home from "@/components/1BASE/1base/base2.vue";
import User from "@/components/4ROUTER/1base/User.vue";
import Product from "@/components/4ROUTER/1base/product.vue";
import UserPosts from "@/components/4ROUTER/1base/userposts.vue";
import UserProfile from "@/components/4ROUTER/1base/userprofile.vue";
import UserProp from "@/components/4ROUTER/1base/UserProp.vue";
import UserSettings from "@/components/4ROUTER/1base/UserSettings.vue";
import ComA from "@/components/4ROUTER/2keepAlived/ComA.vue";
import ComB from "@/components/4ROUTER/2keepAlived/ComB.vue";
import ComC from "@/components/4ROUTER/2keepAlived/ComC.vue";
 
//配置路由映射规则
const routes = [
  // 静态路由
  { path: "/", component: Home },
  { 
    path: "/about", 
    component: About,
    /**
     * beforeEnter 守卫 只在进入路由时触发
     * 
     * @param {Object} to - 表示即将进入的路由信息
     * @param {Object} from - 表示当前即将离开的路由信息
     * @returns {Boolean} 总是返回true，表示允许继续执行下一个钩子或测试用例
     */
    beforeEnter: (to, from) => {
      console.log("路由独享的守卫beforeEach:\nfrom:", from,"\nto:", to);
      return true;
    }
  },
  // 带参数的动态路由匹配，动态字段以冒号开始
  { 
    path: '/users/:id', 
    component: User ,
    beforeEnter: (to, from) => {
      console.log("路由独享的守卫beforeEach:\nfrom:", from,"\nto:", to);
      return true;
    },
    // 嵌套路由
    children: [
      // 当 /user/:id/profile 匹配成功
      // UserProfile 将被渲染到 User 的 <router-view> 内部
      { path: 'profile', component: UserProfile },
      // 当 /user/:id/posts 匹配成功
      // UserPosts 将被渲染到 User 的 <router-view> 内部
      { path: 'posts', component: UserPosts }
    ]
  },
  { 
    path: '/users/:id/vvvv/:postId', 
    component: User,
  },
  // 在参数中自定义正则
  { path: '/u/:id(\\d+)',component: User },     // /:id -> 仅匹配数字
  { path: '/u/:productName', component: Product},  // /:productName -> 匹配任何字符，包括/
  // 可重复的参数
  { path: '/p/:productName+', component: Product},  // +（1 个或多个）
  { path: '/p/:productName*', component: Product},  // *（0 个或多个
  // 命名路由
  { path: '/usernames/:id', name: 'usernames', component: User },
  { 
    path: '/userSettings', 
    component: UserSettings,
    children: [
      { path: 'one', component: UserProfile },
      { 
        path: 'two', 
        components: {
          default: UserProfile,
          helper: About
        },
      }
    ]
  },
  // 将 props 传递给路由组件
  // 通过设置 props: true 来配置路由将 id 参数作为 prop 传递给组件
  { path: '/userprop/:id', component: UserProp, props: true },
  
  { path: '/ComA', component: ComA },
  { path: '/ComB', component: ComB },
  { path: '/ComC', component: ComC },
];
//路由实例通过createRouter创建
const router = createRouter({
    // history栈在浏览器中是用于存储用户会话历史（即URL地址）的。
    history: createWebHashHistory(),
    // routes数组，声明路由的匹配规则，是组件和URL的映射关系。
    routes,
});



/**
 * 在路由导航之前全局执行的守卫函数
 * 该函数会在每次路由变更前被调用，用于执行一些全局的前置逻辑
 * 
 * @param {Route} to 即将进入的路由对象，包含了路由的各种信息，如路径、查询参数等
 * @param {Route} from 当前导航正要离开的路由对象，同样包含了路由的各种信息
 * 
 * @returns {string|boolean} 
 *    返回true，表示允许路由导航继续进行
 *                    如果什么都没有，undefined 或返回 true，则导航是有效的，并调用下一个导航守卫
 *    返回false，表示阻止路由导航
 *    返回一个路由地址，表示重定向到该地址
 *                    通过一个路由地址重定向到一个不同的地址，如同调用 router.push()，且可以传入诸如 replace: true 或 name: 'home' 之类的选项。
 *                    它会中断当前的导航，同时用相同的 from 创建一个新导航。
 *    如果遇到了意料之外的情况，可能会抛出一个 Error。这会取消导航并且调用 router.onError() 注册过的回调。
 */
router.beforeEach((to, from) => {
  console.log("全局前置守卫beforeEach:\nfrom:", from,"\nto:",to);
  /*
  if (to.path === "/about") {
    console.log("===全局前置守卫:重定向到该地址");
    return "/";
  }
    */
  return true;
});

/**
 * 在路由解析之前执行的全局守卫函数
 * 该函数主要用于在路由切换前进行一些全局性的检查或处理
 * 
 * @param {Route} to 即将进入的路由对象，包含路径、查询参数等信息
 * @param {Route} from 当前即将离开的路由对象，同样包含路径、查询参数等信息
 * @returns {string|boolean} 返回值为字符串时，表示重定向到的路径；返回true表示继续执行路由解析
 */
router.beforeResolve((to, from) => {
  console.log("全局解析守卫:\nfrom:", from,"\nto:",to);
  /*
  if (to.path === "/about") {
    console.log("===全局解析守卫beforeResolve:重定向到该地址");
    return "/";
  }
    */
  return true;
});

/**
 * 在路由切换后执行的全局后置守卫函数
 * 该函数没有返回值
 * 
 * @param {Object} to 路由切换的目标位置，包含路由路径、查询参数等信息
 * @param {Object} from 路由切换的起始位置，同样包含路由路径、查询参数等信息
 */
router.afterEach((to, from) => {
  console.log("全局后置守卫afterEach:\nfrom:", from,"\nto:",to);
});

//导出，用于main.js注册
export default router;